{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "e3ad935d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "ddf = pd.read_excel(\"../../data/LR-UFLP.xlsx\", header=None)\n",
    "h = ddf.iloc[1, 2:].tolist()\n",
    "f = ddf.iloc[5:, 1].tolist()\n",
    "c = ddf.iloc[5:, 2:].values\n",
    "lambdas = ddf.iloc[2, 2:].tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "19ede514",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[70524.51,\n",
       " 4804.195915547695,\n",
       " 7305.9123755269975,\n",
       " 4187.544571707629,\n",
       " 1890.4936266515303,\n",
       " 532.9970537639329,\n",
       " 9238.803444261323,\n",
       " 1474.5188007059573,\n",
       " 5816.897959645522,\n",
       " 6932.662769642117,\n",
       " 1951.7288618961404,\n",
       " 9362.630783216615,\n",
       " 3168.65649814138,\n",
       " 3874.2581241353414,\n",
       " 2438.5406451752333,\n",
       " 7479.710815657414,\n",
       " 5329.098464758628,\n",
       " 610.488325754126,\n",
       " 8201.561178477252,\n",
       " 5408.948041103434,\n",
       " 372.9699433221367,\n",
       " 7505.864307889551,\n",
       " 5933.6462545597215,\n",
       " 4282.044692268793,\n",
       " 825.2429729051958,\n",
       " 2051.2017106133394,\n",
       " 1209.6357310902329,\n",
       " 8780.561576750491,\n",
       " 8361.9322394298,\n",
       " 9203.846363229823,\n",
       " 951.6475438597948,\n",
       " 9494.903023540992,\n",
       " 511.4997238579422,\n",
       " 4517.163019444772,\n",
       " 4963.650343359034,\n",
       " 4340.263492672447,\n",
       " 9646.903663459683,\n",
       " 8538.985833168144,\n",
       " 7555.170687653421,\n",
       " 8462.259358121475,\n",
       " 5816.9323972081165,\n",
       " 3031.9097511495397,\n",
       " 8624.257087889484,\n",
       " 912.5688185453585,\n",
       " 3389.5606540717436,\n",
       " 5644.704109301309,\n",
       " 4957.933437888133,\n",
       " 9041.408485194244,\n",
       " 3962.663530257702,\n",
       " 867.0992054028482]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lambdas"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "348708ce",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]\n",
      "y [[0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]\n",
      "z_lr 257923.90716962246\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import copy\n",
    "\n",
    "def lr_uflp_data_loader():\n",
    "    ddf = pd.read_excel(\"../data/LR-UFLP.xlsx\", header=None)\n",
    "    h = ddf.iloc[1, 2:].tolist()\n",
    "    f = ddf.iloc[5:, 1].tolist()\n",
    "    c = ddf.iloc[5:, 2:].values\n",
    "    lambdas = ddf.iloc[2, 2:].tolist()\n",
    "    alpha = 2\n",
    "    gama = 20\n",
    "    kappa = 0.00000001\n",
    "    zeta = 10000\n",
    "    I = list(range(len(h)))\n",
    "    J = list(range(len(f)))\n",
    "    return I, J, h, f, c, lambdas, alpha, gama, kappa, zeta\n",
    "\n",
    "\n",
    "# 8.1\n",
    "def UFLP_LR_lambda(multi_lambdas, I, J, h, f, c):\n",
    "    x = [0 for _ in range(len(J))]\n",
    "    y = [[0 for j in range(len(J))] for i in range(len(I))]\n",
    "    beta = [0 for _ in range(len(J))]\n",
    "    for j in J:\n",
    "        beta[j] = sum([min(0, h[i]*c[i][j] - multi_lambdas[i]) for i in I])\n",
    "        if beta[j] + f[j] < 0:\n",
    "            x[j] = 1\n",
    "            for i in I:\n",
    "                if h[i] * c[i][j] - multi_lambdas[i] < 0:\n",
    "                    y[i][j] = 1\n",
    "                else:\n",
    "                    y[i][j] = 0\n",
    "        else:\n",
    "            x[j] = 0\n",
    "            for i in I:\n",
    "                y[i][j] = 0\n",
    "\n",
    "    z_lr = sum([min(0, beta[j] + f[j]) for j in J]) + sum([multi_lambdas[i] for i in I])\n",
    "\n",
    "    return x, y, z_lr\n",
    "I, J, h, f, c, lambdas, alpha, gama, kappa, zeta = lr_uflp_data_loader()\n",
    "x, y, z_lr = UFLP_LR_lambda(lambdas, I, J, h, f, c)\n",
    "print(\"x\",x)\n",
    "print(\"y\",y)\n",
    "print('z_lr',z_lr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import copy\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "# 8.1\n",
    "def UFLP_LR_lambda(multi_lambdas, I, J, h, f, c):\n",
    "    x = [0 for _ in range(len(J))]\n",
    "    y = [[0 for j in range(len(J))] for i in range(len(I))]\n",
    "    beta = [0 for _ in range(len(J))]\n",
    "    for j in J:\n",
    "        beta[j] = sum([min(0, h[i]*c[i][j] - multi_lambdas[i]) for i in I])\n",
    "        if beta[j] + f[j] < 0:\n",
    "            x[j] = 1\n",
    "            for i in I:\n",
    "                if h[i] * c[i][j] - multi_lambdas[i] < 0:\n",
    "                    y[i][j] = 1\n",
    "                else:\n",
    "                    y[i][j] = 0\n",
    "        else:\n",
    "            x[j] = 0\n",
    "            for i in I:\n",
    "                y[i][j] = 0\n",
    "\n",
    "    z_lr = sum([min(0, beta[j] + f[j]) for j in J]) + sum([multi_lambdas[i] for i in I])\n",
    "\n",
    "    return x, y, z_lr\n",
    "# 8.2\n",
    "def get_feasible_solution(I, J, x_bar, y_bar, h, f, c):\n",
    "    y = copy.deepcopy(y_bar)\n",
    "    for i in I:\n",
    "        \n",
    "        j_s = 0\n",
    "        for j in J[1:]:\n",
    "            if c[i][j] < c[i][j_s] and x_bar[j] == 1 or x_bar[j_s] == 0:\n",
    "                \n",
    "                j_s = j\n",
    "                \n",
    "        y[i][j_s] = 1\n",
    "        for j in J:\n",
    "            if j != j_s:\n",
    "                y[i][j] = 0\n",
    "            \n",
    "            \n",
    "    zxy = sum([f[j] * x_bar[j] for j in J]) + sum([sum([h[i]*c[i][j]*y[i][j] for j in J]) for i in I])\n",
    "\n",
    "    \n",
    "    return x_bar, y, zxy\n",
    "\n",
    "\n",
    "def dataloader_88node(filename):\n",
    "    node_data = pd.read_excel(\"..\\\\data\\\\\" + filename, header=None, sheet_name='Node Data')\n",
    "    trans_costs_and_distances = pd.read_excel(\"..\\\\data\\\\\" + filename, header=None, sheet_name='Trans Cost and Distances')\n",
    "\n",
    "    nd = node_data.iloc[1:, :8]\n",
    "    cols = nd.iloc[0,:].values.tolist()\n",
    "    nd.columns = cols\n",
    "    nd = nd.iloc[1:, :]\n",
    "    h = nd['Demand'].tolist()\n",
    "    f = [i for i in nd['Fixed Cost'].tolist()]\n",
    "    trans_costs = trans_costs_and_distances.iloc[2:90, 1:89]\n",
    "    c = trans_costs.values\n",
    "    longitudes = node_data.iloc[2:, 1].map(lambda x: 180 - x).tolist()\n",
    "    latitudes = node_data.iloc[2:, 2].tolist()\n",
    "    lambdas = [1000000 for i in range(88)]\n",
    "    alpha = 2\n",
    "    gama = 20\n",
    "    kappa = 0.00000001\n",
    "    zeta = 10000\n",
    "\n",
    "    return h, f, c, lambdas, alpha, gama, kappa, zeta, longitudes, latitudes\n",
    "\n",
    "\n",
    "def dataloader_10node(filename):\n",
    "    df = pd.read_excel(\"../../data/10node.xlsx\", header=None)\n",
    "    node = df.iloc[2:12, 3:5]\n",
    "    node.columns = df.iloc[1, 3:5].tolist()\n",
    "    h = node['Demand'].tolist()\n",
    "    f = node['Fixed Cost'].tolist()\n",
    "    cost = df.iloc[15:25, 1:11]\n",
    "    c = cost.values\n",
    "\n",
    "    lambdas = [1000 for i in range(88)]\n",
    "    alpha = 2\n",
    "    gama = 20\n",
    "    kappa = 0.00000001\n",
    "    zeta = 10000\n",
    "\n",
    "    return h, f, c, lambdas, alpha, gama, kappa, zeta\n",
    "\n",
    "# 8.3\n",
    "def lag_relax_algo(filename):\n",
    "    t = 0\n",
    "    LB = -float('inf')\n",
    "    UB = float('inf')\n",
    "    xub = 0\n",
    "    yub = 0\n",
    "    nonimprctr = 0\n",
    "\n",
    "    h, f, c = None, None, None\n",
    "\n",
    "    if filename == '88node.xlsx':\n",
    "        h, f, c, lambdas, alpha, gama, kappa, zeta, longitudes, latitudes = dataloader_88node(filename)\n",
    "    if filename == '10node.xlsx':\n",
    "        h, f, c, lambdas, alpha, gama, kappa, zeta = dataloader_10node(filename)\n",
    "\n",
    "    I = list(range(len(h)))\n",
    "    J = list(range(len(f)))\n",
    "\n",
    "\n",
    "    while True:\n",
    "        x_bar, y_bar, z_lr = UFLP_LR_lambda(lambdas, I, J, h, f, c)\n",
    "        if z_lr > LB:\n",
    "            LB = z_lr\n",
    "            nonimprctr = 0\n",
    "        else:\n",
    "            nonimprctr = nonimprctr + 1\n",
    "            if nonimprctr == gama:\n",
    "                alpha = alpha / 2\n",
    "                nonimprctr = 0\n",
    "        \n",
    "        x, y, zxy = get_feasible_solution(I, J, x_bar, y_bar, h, f, c)\n",
    "        if zxy < UB:\n",
    "            UB = zxy\n",
    "            xub, yub = x, y\n",
    "        print('iter', t,  'LB', LB, 'UB', UB)\n",
    "        tmp = sum([(1 - sum([y_bar[i][j] for j in J]))**2 for i in I])\n",
    "        if tmp == 0:\n",
    "            break\n",
    "        delta = (alpha * (UB - z_lr)) / tmp\n",
    "        for i in I:\n",
    "            lambdas[i] = lambdas[i] + delta * (1 - sum([y_bar[i][j] for j in J]))\n",
    "            \n",
    "        t = t + 1\n",
    "\n",
    "\n",
    "        if UB - z_lr <= kappa or t > zeta:\n",
    "            break\n",
    "\n",
    "    \n",
    "    return xub, yub, UB, longitudes, latitudes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a40da84b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 163,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iter 0 LB -69979.47788262888 UB 2000.0\n",
      "iter 1 LB -5995.439529473087 UB 1589.5982621473631\n",
      "iter 2 LB -5995.439529473087 UB 1589.5982621473631\n",
      "iter 3 LB -5078.87519705143 UB 1589.5982621473631\n",
      "iter 4 LB -5078.87519705143 UB 1589.5982621473631\n",
      "iter 5 LB -4162.310864629767 UB 1589.5982621473631\n",
      "iter 6 LB -4162.310864629767 UB 1589.5982621473631\n",
      "iter 7 LB -3245.7465322081043 UB 1589.5982621473631\n",
      "iter 8 LB -3245.7465322081043 UB 1589.5982621473631\n",
      "iter 9 LB -2430.28675500572 UB 1589.5982621473631\n",
      "iter 10 LB -2430.28675500572 UB 1589.5982621473631\n",
      "iter 11 LB -1757.7964837408706 UB 1589.5982621473631\n",
      "iter 12 LB -1757.7964837408706 UB 1589.5982621473631\n",
      "iter 13 LB -1100.0623774191324 UB 1589.5982621473631\n",
      "iter 14 LB -1100.0623774191324 UB 1589.5982621473631\n",
      "iter 15 LB -303.9018838868434 UB 1565.4194746436353\n",
      "iter 16 LB -303.9018838868434 UB 1565.4194746436353\n",
      "iter 17 LB 16.224811986946094 UB 1465.082306673212\n",
      "iter 18 LB 16.224811986946094 UB 1465.082306673212\n",
      "iter 19 LB 271.7368788781483 UB 1305.6777233155276\n",
      "iter 20 LB 271.7368788781483 UB 1305.6777233155276\n",
      "iter 21 LB 641.7239330655369 UB 1305.6777233155276\n",
      "iter 22 LB 641.7239330655369 UB 1305.6777233155276\n",
      "iter 23 LB 964.0087762527706 UB 1147.8567711908609\n",
      "iter 24 LB 964.0087762527706 UB 1147.8567711908609\n",
      "iter 25 LB 1034.8282505930943 UB 1147.8567711908609\n",
      "iter 26 LB 1087.704704943543 UB 1147.8567711908609\n",
      "iter 27 LB 1087.704704943543 UB 1147.8567711908609\n",
      "iter 28 LB 1088.8684355025505 UB 1131.5236946630214\n",
      "iter 29 LB 1093.6494223001177 UB 1131.5236946630214\n",
      "iter 30 LB 1126.737966680653 UB 1131.5236946630214\n",
      "iter 31 LB 1131.5236946630216 UB 1131.5236946630214\n",
      "1131.5236946630214\n"
     ]
    }
   ],
   "source": [
    "# 10node.xlsx\n",
    "filename = '10node.xlsx'\n",
    "xub, yub, UB = lag_relax_algo(filename = filename)\n",
    "\n",
    "print(UB)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iter 0 LB -5884782062.94975 UB 74329000.0\n",
      "iter 1 LB -51403959.94308436 UB 27019279.241832167\n",
      "iter 2 LB -51403959.94308436 UB 27019279.241832167\n",
      "iter 3 LB -51403959.94308436 UB 19288127.577659667\n",
      "iter 4 LB -51403959.94308436 UB 19288127.577659667\n",
      "iter 5 LB -12511891.39847374 UB 19060236.570445456\n",
      "iter 6 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 7 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 8 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 9 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 10 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 11 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 12 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 13 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 14 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 15 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 16 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 17 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 18 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 19 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 20 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 21 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 22 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 23 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 24 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 25 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 26 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 27 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 28 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 29 LB -10522085.84492227 UB 14449043.618543856\n",
      "iter 30 LB 32909.97536703339 UB 14124141.977372916\n",
      "iter 31 LB 1341514.4990306583 UB 14124141.977372916\n",
      "iter 32 LB 1341514.4990306583 UB 14124141.977372916\n",
      "iter 33 LB 1341514.4990306583 UB 14124141.977372916\n",
      "iter 34 LB 1341514.4990306583 UB 14124141.977372916\n",
      "iter 35 LB 2589581.1787243164 UB 12141230.429771157\n",
      "iter 36 LB 2953043.983784715 UB 12141230.429771157\n",
      "iter 37 LB 2953043.983784715 UB 12141230.429771157\n",
      "iter 38 LB 2953043.983784715 UB 12141230.429771157\n",
      "iter 39 LB 2953043.983784715 UB 12141230.429771157\n",
      "iter 40 LB 2953043.983784715 UB 12141230.429771157\n",
      "iter 41 LB 2953043.983784715 UB 12141230.429771157\n",
      "iter 42 LB 4648657.637759141 UB 12141230.429771157\n",
      "iter 43 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 44 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 45 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 46 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 47 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 48 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 49 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 50 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 51 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 52 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 53 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 54 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 55 LB 6061895.713984424 UB 12141230.429771157\n",
      "iter 56 LB 6323433.93520166 UB 11932354.867733594\n",
      "iter 57 LB 6715167.763443745 UB 11932354.867733594\n",
      "iter 58 LB 6715167.763443745 UB 11932354.867733594\n",
      "iter 59 LB 6715167.763443745 UB 11932354.867733594\n",
      "iter 60 LB 6715167.763443745 UB 11932354.867733594\n",
      "iter 61 LB 6715167.763443745 UB 10868178.75018778\n",
      "iter 62 LB 6715167.763443745 UB 10868178.75018778\n",
      "iter 63 LB 6715167.763443745 UB 10868178.75018778\n",
      "iter 64 LB 6715167.763443745 UB 10868178.75018778\n",
      "iter 65 LB 6715167.763443745 UB 10868178.75018778\n",
      "iter 66 LB 6715167.763443745 UB 10868178.75018778\n",
      "iter 67 LB 6715167.763443745 UB 10868178.75018778\n",
      "iter 68 LB 6715167.763443745 UB 10868178.75018778\n",
      "iter 69 LB 6715167.763443745 UB 10612617.140437115\n",
      "iter 70 LB 6715167.763443745 UB 10612617.140437115\n",
      "iter 71 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 72 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 73 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 74 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 75 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 76 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 77 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 78 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 79 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 80 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 81 LB 6876886.071956475 UB 9836147.647196496\n",
      "iter 82 LB 7196779.873439541 UB 9836147.647196496\n",
      "iter 83 LB 7196779.873439541 UB 9836147.647196496\n",
      "iter 84 LB 7196779.873439541 UB 9836147.647196496\n",
      "iter 85 LB 7196779.873439541 UB 9836147.647196496\n",
      "iter 86 LB 7196779.873439541 UB 9836147.647196496\n",
      "iter 87 LB 7196779.873439541 UB 9836147.647196496\n",
      "iter 88 LB 7196779.873439541 UB 9836147.647196496\n",
      "iter 89 LB 7196779.873439541 UB 9836147.647196496\n",
      "iter 90 LB 7427429.994034532 UB 9481762.88482937\n",
      "iter 91 LB 7427429.994034532 UB 9481762.88482937\n",
      "iter 92 LB 7427429.994034532 UB 9481762.88482937\n",
      "iter 93 LB 7427429.994034532 UB 9481762.88482937\n",
      "iter 94 LB 7427429.994034532 UB 9481762.88482937\n",
      "iter 95 LB 7427429.994034532 UB 9481762.88482937\n",
      "iter 96 LB 7523112.215539526 UB 9481762.88482937\n",
      "iter 97 LB 7523112.215539526 UB 9481762.88482937\n",
      "iter 98 LB 7523112.215539526 UB 9481762.88482937\n",
      "iter 99 LB 7523112.215539526 UB 9481762.88482937\n",
      "iter 100 LB 7523112.215539526 UB 9481762.88482937\n",
      "iter 101 LB 7523112.215539526 UB 9481762.88482937\n",
      "iter 102 LB 7523112.215539526 UB 9481762.88482937\n",
      "iter 103 LB 7523112.215539526 UB 9481762.88482937\n",
      "iter 104 LB 7561097.38366745 UB 8542924.478314998\n",
      "iter 105 LB 7561097.38366745 UB 8542924.478314998\n",
      "iter 106 LB 7561097.38366745 UB 8542924.478314998\n",
      "iter 107 LB 7561097.38366745 UB 8542924.478314998\n",
      "iter 108 LB 7561097.38366745 UB 8542924.478314998\n",
      "iter 109 LB 7561097.38366745 UB 8542924.478314998\n",
      "iter 110 LB 7561097.38366745 UB 8542924.478314998\n",
      "iter 111 LB 7690548.342953178 UB 8542924.478314998\n",
      "iter 112 LB 7690548.342953178 UB 8542924.478314998\n",
      "iter 113 LB 7690548.342953178 UB 8542924.478314998\n",
      "iter 114 LB 7690548.342953178 UB 8542924.478314998\n",
      "iter 115 LB 7690548.342953178 UB 8542924.478314998\n",
      "iter 116 LB 7690548.342953178 UB 8542924.478314998\n",
      "iter 117 LB 7690548.342953178 UB 8542924.478314998\n",
      "iter 118 LB 7690548.342953178 UB 8542924.478314998\n",
      "iter 119 LB 7690548.342953178 UB 8199802.184786884\n",
      "iter 120 LB 7690548.342953178 UB 8199802.184786884\n",
      "iter 121 LB 7690548.342953178 UB 8199802.184786884\n",
      "iter 122 LB 7726949.970636213 UB 8199802.184786884\n",
      "iter 123 LB 7726949.970636213 UB 8199802.184786884\n",
      "iter 124 LB 7726949.970636213 UB 8199802.184786884\n",
      "iter 125 LB 7726949.970636213 UB 8199802.184786884\n",
      "iter 126 LB 7726949.970636213 UB 8199802.184786884\n",
      "iter 127 LB 7726949.970636213 UB 8199802.184786884\n",
      "iter 128 LB 7730093.981045122 UB 8199802.184786884\n",
      "iter 129 LB 7730093.981045122 UB 8199802.184786884\n",
      "iter 130 LB 7730093.981045122 UB 8199802.184786884\n",
      "iter 131 LB 7730093.981045122 UB 8199802.184786884\n",
      "iter 132 LB 7730093.981045122 UB 8199802.184786884\n",
      "iter 133 LB 7747951.956334685 UB 8199802.184786884\n",
      "iter 134 LB 7747951.956334685 UB 8199802.184786884\n",
      "iter 135 LB 7747951.956334685 UB 8199802.184786884\n",
      "iter 136 LB 7747951.956334685 UB 8135557.005183696\n",
      "iter 137 LB 7747951.956334685 UB 8135557.005183696\n",
      "iter 138 LB 7747951.956334685 UB 8135557.005183696\n",
      "iter 139 LB 7797283.225284569 UB 7935194.119327349\n",
      "iter 140 LB 7797283.225284569 UB 7935194.119327349\n",
      "iter 141 LB 7797283.225284569 UB 7935194.119327349\n",
      "iter 142 LB 7797283.225284569 UB 7935194.119327349\n",
      "iter 143 LB 7809301.037934366 UB 7935194.119327349\n",
      "iter 144 LB 7809301.037934366 UB 7935194.119327349\n",
      "iter 145 LB 7809301.037934366 UB 7935194.119327349\n",
      "iter 146 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 147 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 148 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 149 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 150 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 151 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 152 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 153 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 154 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 155 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 156 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 157 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 158 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 159 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 160 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 161 LB 7814605.735649546 UB 7935194.119327349\n",
      "iter 162 LB 7817517.733031979 UB 7935194.119327349\n",
      "iter 163 LB 7817517.733031979 UB 7935194.119327349\n",
      "iter 164 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 165 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 166 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 167 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 168 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 169 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 170 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 171 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 172 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 173 LB 7818226.208803089 UB 7935194.119327349\n",
      "iter 174 LB 7818660.862896882 UB 7935194.119327349\n",
      "iter 175 LB 7818660.862896882 UB 7935194.119327349\n",
      "iter 176 LB 7818660.862896882 UB 7935194.119327349\n",
      "iter 177 LB 7818660.862896882 UB 7935194.119327349\n",
      "iter 178 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 179 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 180 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 181 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 182 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 183 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 184 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 185 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 186 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 187 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 188 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 189 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 190 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 191 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 192 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 193 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 194 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 195 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 196 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 197 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 198 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 199 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 200 LB 7826587.811349475 UB 7935194.119327349\n",
      "iter 201 LB 7837467.340628754 UB 7838133.045156726\n",
      "iter 202 LB 7837783.7244291855 UB 7838133.045156726\n",
      "iter 203 LB 7837958.3847929565 UB 7838133.045156726\n",
      "iter 204 LB 7838045.71497484 UB 7838133.045156726\n",
      "iter 205 LB 7838089.380065783 UB 7838133.045156726\n",
      "iter 206 LB 7838111.212611255 UB 7838133.045156726\n",
      "iter 207 LB 7838122.12888399 UB 7838133.045156726\n",
      "iter 208 LB 7838127.587020357 UB 7838133.045156726\n",
      "iter 209 LB 7838130.316088541 UB 7838133.045156726\n",
      "iter 210 LB 7838131.6806226345 UB 7838133.045156726\n",
      "iter 211 LB 7838132.36288968 UB 7838133.045156726\n",
      "iter 212 LB 7838132.704023202 UB 7838133.045156726\n",
      "iter 213 LB 7838132.874589964 UB 7838133.045156726\n",
      "iter 214 LB 7838132.959873346 UB 7838133.045156726\n",
      "iter 215 LB 7838133.002515036 UB 7838133.045156726\n",
      "iter 216 LB 7838133.02383588 UB 7838133.045156726\n",
      "iter 217 LB 7838133.034496303 UB 7838133.045156726\n",
      "iter 218 LB 7838133.039826515 UB 7838133.045156726\n",
      "iter 219 LB 7838133.0424916195 UB 7838133.045156726\n",
      "iter 220 LB 7838133.043824173 UB 7838133.045156726\n",
      "iter 221 LB 7838133.04449045 UB 7838133.045156726\n",
      "iter 222 LB 7838133.044823588 UB 7838133.045156726\n",
      "iter 223 LB 7838133.044990157 UB 7838133.045156726\n",
      "iter 224 LB 7838133.045073441 UB 7838133.045156726\n",
      "iter 225 LB 7838133.0451150825 UB 7838133.045156726\n",
      "iter 226 LB 7838133.045135905 UB 7838133.045156726\n",
      "iter 227 LB 7838133.045146315 UB 7838133.045156726\n",
      "iter 228 LB 7838133.04515152 UB 7838133.045156726\n",
      "iter 229 LB 7838133.045154124 UB 7838133.045156726\n",
      "iter 230 LB 7838133.045155424 UB 7838133.045156726\n",
      "iter 231 LB 7838133.045156076 UB 7838133.045156726\n",
      "iter 232 LB 7838133.0451564 UB 7838133.045156726\n",
      "iter 233 LB 7838133.045156564 UB 7838133.045156726\n",
      "iter 234 LB 7838133.045156644 UB 7838133.045156726\n",
      "iter 235 LB 7838133.045156685 UB 7838133.045156726\n",
      "iter 236 LB 7838133.045156705 UB 7838133.045156726\n",
      "iter 237 LB 7838133.045156716 UB 7838133.045156726\n",
      "7838133.045156726\n"
     ]
    }
   ],
   "source": [
    "# 88node.xlsx\n",
    "filename = '88node.xlsx'\n",
    "xub, yub, UB, longitudes, latitudes = lag_relax_algo(filename = filename)\n",
    "\n",
    "print(UB)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0bc8dc11",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "for i in range(len(xub)):\n",
    "    for j in range(len(yub)):\n",
    "        if yub[i][j] == 1:\n",
    "            plt.plot([longitudes[i], longitudes[j]], [latitudes[i], latitudes[j]])\n",
    "plt.show()\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.9.12 ('base')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  },
  "vscode": {
   "interpreter": {
    "hash": "5179d32cf6ec497baf3f8a3ef987cc77c5d2dc691fdde20a56316522f61a7323"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
